home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / mesa / mesa-tk / glue / genglue.in < prev    next >
Text File  |  2000-02-23  |  6KB  |  227 lines

  1. #include <sys/types.h>
  2. #include <sys/syscall.h>
  3.  
  4. #include <stdio.h>
  5.  
  6. struct syscall {
  7.   char *name;
  8.   int   vec;
  9. } syscalls[] = {
  10. #define SYSTEM_CALL(func,vec) { #func, vec},
  11. #include "../include/GL/gl@TARGET@_calls.def"
  12. #undef SYSTEM_CALL
  13. };
  14.  
  15. int nsyscall = sizeof(syscalls) / sizeof (syscalls[0]);
  16.  
  17. #define MesaGL@TARGET@BASE "_MesaGL@TARGET@base"
  18. #define MesaGL@TARGET@BASELEN (sizeof(MesaGL@TARGET@BASE) - 1)
  19.  
  20. #define BASEREL_OFFSET1 19
  21. #define BASEREL_OFFSET2 31
  22.  
  23. /* The following code is a hexdump of this assembly program:
  24.  
  25.         .globl    _FUNCTION
  26. _FUNCTION:    movel    a4@(_MesaGL@TARGET@base:W),a0
  27.         jmp    a0@(OFFSET:w)
  28. */
  29.  
  30. static short baserel_code[] = {
  31.   0x0000, 0x0107, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000,
  32.   0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000,
  33.   0x206c, 0x0000, 0x4ee8, 0xff46, 0x0000, 0x0002, 0x0000, 0x0138,
  34.   0x0000, 0x0004, 0x0500, 0x0000, 0x0000, 0x0000, 0x0000, 0x0011,
  35.   0x0100, 0x0000, 0x0000, 0x0000
  36. };
  37.  
  38. #define LARGE_BASEREL_OFFSET1 21
  39. #define LARGE_BASEREL_OFFSET2 33
  40.  
  41. /* The following code is a hexdump of this assembly program:
  42.  
  43.         .globl    _FUNCTION
  44. _FUNCTION:    movel    a4@(_MesaGL@TARGET@base:L),a0
  45.         jmp    a0@(OFFSET:w)
  46. */
  47.  
  48. static short large_baserel_code[] = {
  49.   0x0000, 0x0107, 0x0000, 0x000c, 0x0000, 0x0000, 0x0000, 0x0000,
  50.   0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000,
  51.   0x2074, 0x0170, 0x0000, 0x0000, 0x4ee8, 0xffe2, 0x0000, 0x0004,
  52.   0x0000, 0x0158, 0x0000, 0x0004, 0x0500, 0x0000, 0x0000, 0x0000,
  53.   0x0000, 0x000e, 0x0100, 0x0000, 0x0000, 0x0000
  54. };
  55.  
  56. #define NO_BASEREL_OFFSET1 20
  57. #define NO_BASEREL_OFFSET2 33
  58.  
  59. /* The following code is a hexdump of this assembly program:
  60.  
  61.         .globl    _FUNCTION
  62. _FUNCTION:    movel    _MesaGL@TARGET@base,a0
  63.         jmp    a0@(OFFSET:w)
  64. */
  65.  
  66. static short no_baserel_code[] = {
  67.   0x0000, 0x0107, 0x0000, 0x000c, 0x0000, 0x0000, 0x0000, 0x0000,
  68.   0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000,
  69.   0x2079, 0x0000, 0x0000, 0x4ee8, 0xffe2, 0x0000, 0x0000, 0x0002,
  70.   0x0000, 0x0150, 0x0000, 0x0004, 0x0500, 0x0000, 0x0000, 0x0000,
  71.   0x0000, 0x000b, 0x0100, 0x0000, 0x0000, 0x0000
  72. };
  73.  
  74. #define PROFILING_OFFSET1 29
  75. #define PROFILING_OFFSET2 51
  76. #define PROFILING_OFFSET3 57
  77. #define PROFILING_OFFSET4 63
  78.  
  79. /* The following code is a hexdump of this assembly program:
  80.  
  81.         .globl    _FUNCTION
  82. _FUNCTION:
  83.         .data
  84. PROFFUNCTION:
  85.         .long    0
  86.  
  87.         .text
  88.         link    a5,#0
  89.         lea    PROFFUNCTION,a0
  90.         jsr    mcount
  91.         unlk    a5
  92.         movel    _MesaGL@TARGET@base,a0
  93.         jmp    a0@(OFFSET:w)
  94. */
  95.  
  96. static short profiling_code[] = {
  97.   0x0000, 0x0107, 0x0000, 0x001c, 0x0000, 0x0004, 0x0000, 0x0000,
  98.   0x0000, 0x0030, 0x0000, 0x0000, 0x0000, 0x0018, 0x0000, 0x0000,
  99.   0x4e55, 0x0000, 0x41f9, 0x0000, 0x001c, 0x4eb9, 0x0000, 0x0000,
  100.   0x4e5d, 0x2079, 0x0000, 0x0000, 0x4ee8, 0xffe2, 0x0000, 0x0000,
  101.   0x0000, 0x0006, 0x0000, 0x0640, 0x0000, 0x000c, 0x0000, 0x0250,
  102.   0x0000, 0x0014, 0x0000, 0x0350, 0x0000, 0x0004, 0x0500, 0x0000,
  103.   0x0000, 0x0000, 0x0000, 0x000b, 0x0600, 0x0000, 0x0000, 0x001c,
  104.   0x0000, 0x0015, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x001c,
  105.   0x0100, 0x0000, 0x0000, 0x0000
  106. };
  107.  
  108. void usage(void)
  109. {
  110.   fprintf(stderr, "Usage: gen_glue baserel | large-baserel | no-baserel | profiling\n");
  111.   exit(1);
  112. }
  113.  
  114. void write_code(short *code, int len, FILE *f)
  115. {
  116.   const short endian = 0x0100;
  117.  
  118.   /* test if gen_glue is compiled on a big or little endian machine */
  119.   if (((char *)&endian)[0])
  120.   {
  121.     fwrite(code, len, 1, f);        /* big endian */
  122.   }
  123.   else
  124.   {
  125.     int i;
  126.  
  127.     for (i = 0; i < len / 2; i++)
  128.     {
  129.       short x = code[i];        /* little endian */
  130.       
  131.       fputc(((char *)&x)[1], f);
  132.       fputc(((char *)&x)[0], f);
  133.     }
  134.   }
  135. }
  136.  
  137. int main(int argc, char **argv)
  138. {
  139.   FILE *fp;
  140.   struct syscall *sc;
  141.   int i, v, baserel = 0, profiling = 0, lbaserel = 0;
  142.   short *code;
  143.   int offset1, offset2, size;
  144.   int zero = 0;
  145.  
  146.   if (argc != 2)
  147.     usage();
  148.   if (!strcmp(argv[1], "baserel"))
  149.     baserel = 1;
  150.   else if (!strcmp(argv[1], "baserel32"))
  151.     lbaserel = 1;
  152.   else if (!strcmp(argv[1], "profiling"))
  153.     profiling = 1;
  154.   else if (strcmp(argv[1], "no-baserel"))
  155.     usage();
  156.   
  157.   for (i = 0, sc = syscalls; i < nsyscall; i++, sc++)
  158.     {
  159.       int namelen = strlen(sc->name);
  160.       char name[namelen + 3];
  161.  
  162.       if (!memcmp(sc->name, "__obsolete", 10))
  163.         continue;
  164.       if (!memcmp(sc->name, "__must_recompile", 16))
  165.         continue;
  166.       if (!memcmp(sc->name, "__stk", 5))
  167.         continue;
  168.       v = -(sc->vec + 4) * 6;
  169.       sprintf (name, "%s.o", sc->name);
  170.  
  171.       fp = fopen (name, "w");
  172.       
  173.       if (!fp)
  174.         {
  175.           perror (sc->name);
  176.           exit (20);
  177.         }
  178.  
  179.       code = no_baserel_code;
  180.       size = sizeof(no_baserel_code);
  181.       offset1 = NO_BASEREL_OFFSET1;
  182.       offset2 = NO_BASEREL_OFFSET2;
  183.       if (profiling)
  184.         {
  185.           profiling_code[PROFILING_OFFSET1] = v;
  186.           profiling_code[PROFILING_OFFSET2] = 6 + namelen;
  187.           profiling_code[PROFILING_OFFSET3] = 6 + namelen * 2 + 5;
  188.           profiling_code[PROFILING_OFFSET4] = 6 + namelen * 2 + 5 + 7;
  189.           write_code(profiling_code, sizeof(profiling_code), fp);
  190.           fwrite(&zero, 3, 1, fp);
  191.           fputc((char)(namelen * 2 + 7 + MesaGL@TARGET@BASELEN + 1 + 7 + 4), fp);
  192.           fputc('_', fp);
  193.           fwrite(sc->name, namelen + 1, 1, fp);
  194.           fprintf(fp, "PROF");
  195.           fwrite(sc->name, namelen + 1, 1, fp);
  196.           fwrite("mcount", 7, 1, fp);
  197.         }
  198.       else
  199.     {
  200.       if (baserel && sc->vec != SYS_ix_geta4)
  201.         {
  202.               code = baserel_code;
  203.               size = sizeof(baserel_code);
  204.               offset1 = BASEREL_OFFSET1;
  205.               offset2 = BASEREL_OFFSET2;
  206.             }
  207.       else if (lbaserel && sc->vec != SYS_ix_geta4)
  208.         {
  209.               code = large_baserel_code;
  210.               size = sizeof(large_baserel_code);
  211.               offset1 = LARGE_BASEREL_OFFSET1;
  212.               offset2 = LARGE_BASEREL_OFFSET2;
  213.             }
  214.           code[offset1] = v;
  215.           code[offset2] = namelen + 4 + 2;
  216.           write_code(code, size, fp);
  217.           fwrite(&zero, 3, 1, fp);
  218.           fputc((char)(namelen + 2 + MesaGL@TARGET@BASELEN + 1 + 4), fp);
  219.           fputc('_', fp);
  220.           fwrite(sc->name, namelen + 1, 1, fp);
  221.         }
  222.       fwrite(MesaGL@TARGET@BASE, MesaGL@TARGET@BASELEN + 1, 1, fp);
  223.       fclose (fp);
  224.     }
  225.   exit(0);
  226. }
  227.